#pragma once

#include <algorithm>
#include <functional>
#include <set>

namespace SetMath{
    template<typename T>
    std::set<T> XOR(const std::set<T> & a, const std::set<T> & b){
        std::set<T> result;
        for(T val : a){
            if(find(b.begin(), b.end(), val) != b.end()){
                continue;
            }
            result.insert(val);
        }
        for(T val : b){
            if(find(a.begin(), a.end(), val) != a.end()){
                continue;
            }
            result.insert(val);
        }

        return result;
    }

    template<typename T>
    std::set<T> OR(const std::set<T> & a, const std::set<T> & b){
        std::set<T> result = a;
        for(T val : b){
            result.insert(val);
        }
        return result;
    }

    template<typename T>
    std::set<T> AND(const std::set<T> & a, const std::set<T> & b){
        std::set<T> result;
        for(T val : a){
            if(find(b.begin(), b.end(), val) != b.end()){
                result.insert(val);
            }
        }
        return result;
    }
}

